package com.hlk.article.service.impl;

import com.github.pagehelper.PageHelper;
import com.hlk.article.mapper.ArticleMapper;
import com.hlk.article.service.ArticleService;
import com.hlk.config.RabbitmqConfig;
import com.hlk.enums.ArticleAppointType;
import com.hlk.enums.ArticleReviewStatusEnum;
import com.hlk.enums.ResponseStatusEnum;
import com.hlk.enums.YesOrNo;
import com.hlk.exception.HuaException;
import com.hlk.pojo.Article;
import com.hlk.pojo.bo.NewArticleBO;
import com.hlk.utils.ConvertUtils;
import com.hlk.utils.DateUtil;
import com.hlk.utils.PageResult;
import com.hlk.utils.PageUtils;
import org.apache.commons.lang3.StringUtils;
import org.n3r.idworker.Sid;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private Sid sid;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public void createArticle(NewArticleBO newArticleBO) {
        Article article = ConvertUtils.sourceToTarget(newArticleBO, Article.class);
        article.setId(sid.nextShort());
        article.setArticleStatus(ArticleReviewStatusEnum.REVIEWING.type);
        article.setCommentCounts(0);
        article.setReadCounts(0);
        article.setCreateTime(new Date());
        article.setIsDelete(YesOrNo.NO.type);
        article.setUpdateTime(new Date());

        if (article.getIsAppoint().equals(ArticleAppointType.TIMING.type)) {
            article.setPublishTime(newArticleBO.getPublishTime());
        } else if (article.getIsAppoint().equals(ArticleAppointType.IMMEDIATELY.type)) {
            article.setPublishTime(new Date());
        }

        int res = articleMapper.insert(article);
        if (res != 1) {
            throw new HuaException(ResponseStatusEnum.ARTICLE_CREATE_ERROR);
        }

        if (article.getIsAppoint().equals(ArticleAppointType.TIMING.type)) {
            // 是定时发布文章
            Date endDate = newArticleBO.getPublishTime();
            Date startDate = new Date();

            int delayTime = (int) (endDate.getTime() - startDate.getTime());
//            int delayTime = 10 * 1000;

            MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
                @Override
                public Message postProcessMessage(Message message) throws AmqpException {
                    // 设置消息持久化
                    message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
                    // 设置消息延迟时间
                    message.getMessageProperties().setDelay(delayTime);
                    return message;
                }
            };

            rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_DELAY, "publish.delay.article", article.getId(), messagePostProcessor);
        }


    }

    @Override
    public PageResult selectMyList(String userId, String keyword, Integer status, Date startDate, Date endDate, Integer page, Integer pageSize) {
        Example example = new Example(Article.class);
        example.orderBy("createTime").desc();
        Example.Criteria criteria = example.createCriteria();

        criteria.andEqualTo("publishUserId", userId);

        if (StringUtils.isNotBlank(keyword)) {
            criteria.andLike("title", "%" + keyword + "%");
        }

        if (ArticleReviewStatusEnum.isArticleStatusValid(status)) {
            criteria.andEqualTo("articleStatus", status);
        }

        if (status != null && status == 12) {
            criteria.andEqualTo("articleStatus", ArticleReviewStatusEnum.REVIEWING.type)
                    .orEqualTo("articleStatus", ArticleReviewStatusEnum.WAITING_MANUAL.type);
        }

        criteria.andEqualTo("isDelete", YesOrNo.NO.type);

        if (startDate != null) {
            criteria.andGreaterThanOrEqualTo("publishTime", startDate);
        }
        if (endDate != null) {
            criteria.andLessThanOrEqualTo("publishTime", endDate);
        }

        PageHelper.startPage(page, pageSize);
        List<Article> list = articleMapper.selectByExample(example);
        return PageUtils.getResult(page, list);
    }

    @Override
    public PageResult selectAllList(Integer status, Integer page, Integer pageSize) {
        Example example = new Example(Article.class);
        example.orderBy("createTime").desc();

        Example.Criteria criteria = example.createCriteria();
        if (ArticleReviewStatusEnum.isArticleStatusValid(status)) {
            criteria.andEqualTo("articleStatus", status);
        }

        // 审核中是机审和人审核的两个状态，所以需要单独判断
        if (status != null && status == 12) {
            criteria.andEqualTo("articleStatus", ArticleReviewStatusEnum.REVIEWING.type)
                    .orEqualTo("articleStatus", ArticleReviewStatusEnum.WAITING_MANUAL.type);
        }

        //isDelete 必须是0
        criteria.andEqualTo("isDelete", YesOrNo.NO.type);

        /**
         * page: 第几页
         * pageSize: 每页显示条数
         */
        PageHelper.startPage(page, pageSize);
        List<Article> list = articleMapper.selectByExample(example);
        return PageUtils.getResult(page, list);
    }

    @Override
    public void updateArticleStatus(String articleId, Integer pendingStatus) {
        Example example = new Example(Article.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("id", articleId);

        Article pendingArticle = new Article();
        pendingArticle.setArticleStatus(pendingStatus);

        int res = articleMapper.updateByExampleSelective(pendingArticle, example);
        if (res != 1) {
            throw new HuaException(ResponseStatusEnum.ARTICLE_REVIEW_ERROR);
        }
    }

    @Override
    public void deleteArticle(String userId, String articleId) {
        Example articleExample = makeExampleCriteria(userId, articleId);

        Article pending = new Article();
        pending.setIsDelete(YesOrNo.YES.type);

        int result = articleMapper.updateByExampleSelective(pending, articleExample);
        if (result != 1) {
            throw new HuaException(ResponseStatusEnum.ARTICLE_DELETE_ERROR);
        }

        // TODO 删除静态页面
//        deleteHTML(articleId);
    }

    @Override
    public void withdrawArticle(String userId, String articleId) {
        Example articleExample = makeExampleCriteria(userId, articleId);

        Article pending = new Article();
        pending.setArticleStatus(ArticleReviewStatusEnum.WITHDRAW.type);

        int result = articleMapper.updateByExampleSelective(pending, articleExample);
        if (result != 1) {
            throw new HuaException(ResponseStatusEnum.ARTICLE_WITHDRAW_ERROR);
        }

        // TODO 删除静态页面
//        deleteHTML(articleId);
    }

    @Override
    public void updateArticleToGridFS(String articleId, String articleMongoId) {
        Article pendingArticle = new Article();
        pendingArticle.setId(articleId);
        pendingArticle.setMongoFileId(articleMongoId);
        articleMapper.updateByPrimaryKeySelective(pendingArticle);
    }

    @Override
    public void updateArticleToPublish(String articleId) {
        Article article = new Article();
        article.setId(articleId);
        article.setIsAppoint(ArticleAppointType.IMMEDIATELY.type);
        articleMapper.updateByPrimaryKeySelective(article);
    }

    private Example makeExampleCriteria(String userId, String articleId) {
        Example articleExample = new Example(Article.class);
        Example.Criteria criteria = articleExample.createCriteria();
        criteria.andEqualTo("publishUserId", userId);
        criteria.andEqualTo("id", articleId);
        return articleExample;
    }
}
